<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            padding: 0px;
            margin: 0px;
            list-style: none;
            box-sizing: border-box;
        }

        .date-box {
            width: 700px;
            margin: auto;
        }

        .date-box-header>h2 {
            font-size: 120%;
            padding: 10px 0px;
        }

        .date-box-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .date-box-header>nav {
            display: flex;
            justify-content: space-between;
        }

        .btns {
            padding: 0px 10px;
            cursor: pointer;
        }

        .date-head,.date-body {
            display: flex;
        }

        .date-body {
            flex-wrap: wrap;
        }

        .date-head>li,.date-body>li {
            width: 100px;
            height: 50px;
            line-height: 50px;
            text-align: center;
            background-color: #efefef;
        }

        
    </style>
</head>
<body>
    <section class="date-box">
        <header class="date-box-header">
            <h2>
            </h2>
            <nav>
                <span class="btns">上一年</span>
                <span class="btns">上一月</span>
                <span class="btns">下一月</span>
                <span class="btns">下一年</span>
            </nav>
        </header>
        <div>
            <ul class="date-head">
                <li>一</li>
                <li>二</li>
                <li>三</li>
                <li>四</li>
                <li>五</li>
                <li>六</li>
                <li>日</li>
            </ul>
            <ul class="date-body">

            </ul>
        </div>
    </section>
</body>
<script>

    let date = new Date();
    let array = [31,28,31,30,31,30,31,31,30,31,30,31];

    let h2 = document.querySelector(".date-box-header>h2");
    let ul = document.querySelector(".date-body");
    let btns = document.querySelectorAll(".btns");

    for (let v of btns) {
        v.addEventListener("click",handleClick); 
    }

    /**
     * 点击按钮事件
     */ 
    function handleClick(e) {
        let target = e.target;

        // 点击年
        function doYear(i) {
            let year = date.getFullYear();
            year -= i;
            date.setFullYear(year);
            print();
        }

        // 点击月
        function doMonth(i) {
            let month = date.getMonth();
            // 12月时点击下一月，进年
            if (month == 11 && i == 1) {
                date.setMonth(0)
                doYear(1);
            // 1月时点击上一月，减年
            } else if (month == 0 && i == -1) {
                date.setMonth(11);
                doYear(-1);
            } else {
                month += i;
                date.setMonth(month);
                print();
            }
        }

        // 上一年
        if (target == btns[0]) {
            doYear(-1);
        // 上一月    
        } else if (target == btns[1]) {
            doMonth(-1);
        // 下一月    
        } else if (target == btns[2]) {
            doMonth(1);
        // 下一年
        } else if (target == btns[3]) {
            doYear(1);
        } 
    }

    /**
     * 根据date表示的时间打印日历
     */
    function print() {
        let month = date.getMonth();
        let year = date.getFullYear();
        // let textNode = document.createTextNode(`${year}年-${month + 1}月`);
        // h2.removeChild(h2.firstChild);
        // h2.appendChild(textNode);
        h2.innerText = `${year}年${month + 1}月`;

        // 清空ul内部
        ul.innerText = "";

        let day = getFirstWeek();
        // 根据第一日是星期几创建前面的空li
        for (let i = 1;i < day;i ++) {
            let li = document.createElement("li");
            // li.innerText = "";
            ul.appendChild(li);
        }

        // 根据当前月有几天，循环生成日期li
        let days = getMonthDays(year,month);
        for (let i = 1;i <= days;i ++) {
            let li = document.createElement("li");
            li.innerText = i;
            ul.appendChild(li);
        }
    }

    /**
     * 计算当前时间第一天是星期几
     */
    function getFirstWeek() {
        // 设置为一日
        date.setDate(1);
        // 返回星期几
        return date.getDay();
    }

    /**
     * 获取当月有多少天
     */ 
    function getMonthDays(year,month) {
        let days = array[month];
        // 二月单独判断：判断是不是闰年
        if (month == 1) {
            if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) {
                return 29;
            }
        }
        return days;
    }



    

    print();

</script>
</html>